<?php
/**
 * Jishupu-Laravel-Vue-Admin
 * @Author:技术铺<jishupu@qq.com>
 * @Date:2021/11/11
 */

namespace App\Traits;


use App\Models\AdminLog;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Illuminate\Support\Str;

/**
 * Trait UnifiedResponse 接口返回统一响应结果结构
 * @package App\Traits
 * 响应结果说明：
 * 1.status：状态 1成功 0错误
 * 2.code：状态码/业务码，格式：状态码.业务码
 * 2.1 如：201.00000，小数点前三位的状态码201必须来源Response定义的状态码常量： Symfony\Component\HttpFoundation\Response
 * 2.2 目前业务码仅作为"规划备用"暂不使用，返回200同完整200.00000
 * 2.3.【！！！重要】为给予用户良好体验，服务器返回客户端的响应状态码除了资源不存在返404、系统内部错误返500以外，其他都设置为200，使用$code数值返回真实的状态码
 * 3.message：成功或错误提示语，生成环境下，提示语中勿要暴露代码
 * 4.data：返回的数据
 * 4.1.带分页列表数据格式：
 * [
 *  current_page: 1
 *  items: []
 *  last_page: 1
 *  per_page: "20"
 *  total: 18
 * ]
 * 4.2.不带分页列表数据格式：
 * [
 *  items: []
 * ]
 * 4.3.详情数据格式：
 * [
 *  id: 1,
 *  title: '标题'
 *  ...
 * ]
 * 5.e_code：异常代码，即admin_log的id标识
 */
trait UnifiedResponse
{
    /**
     * 常用状态码常量
     * 常量-状态码-释义
     * HTTP_OK = 200  请求成功。一般用于GET与POST请求，场景：get获取数据列表、详情等
     * HTTP_CREATED = 201 已创建。成功请求并创建了新的资源，场景：数据不存在、接口不存在、页面不存在等
     * HTTP_NO_CONTENT = 204  无内容。服务器成功处理，但未返回内容 ，场景：用户删除数据成功
     * HTTP_MOVED_PERMANENTLY = 301 重定向。请求的资源已被永久的移动到新URI，返回信息会包括新的URI，浏览器会自动定向到新URI
     * HTTP_BAD_REQUEST = 400 客户端请求的语法错误等，场景：POST/PUT/PATCH 添加、修改、上传等失败场景
     * HTTP_UNAUTHORIZED = 401 请求要求用户的身份认证，场景：令牌失效，登录用户名密码不正确
     * HTTP_FORBIDDEN = 403 服务器理解请求客户端的请求，但是拒绝执行此请求，场景：无访问、操作权限
     * HTTP_NOT_FOUND = 404  服务器无法根据客户端的请求找到资源（网页），场景：数据不存在、接口不存在、页面不存在等
     * HTTP_INTERNAL_SERVER_ERROR = 500 服务器内部错误，无法完成请求，场景：程序有bug等
     *
     * 使用方法，例：Response::HTTP_OK 代表 200
     * 更多状态码参考：
     * @param \Symfony\Component\HttpFoundation\Response
     */

    /**
     * 日志ID
     * @var int
     */
    public $log_id = 0;

    /**
     * 操作异常时使用此方法以将异常信息入库，此方法生成log_id，操作日志记录时以此标识进行更新日志信息
     * @param string $message
     * @return $this
     *
     * 控制器中应用：
     * $this->exception($error_message)->errorStored()
     *
     */
    public function exception($error_message = "")
    {
        $data = [
            'exception' => Str::substr($error_message, 0, 2000)
        ];
        $adminLog = new AdminLog($data);
        $adminLog->save();
        $this->log_id = $adminLog->id;
        return $this;
    }


    /**
     * 场景：操作成功
     * @param string $message
     * @param array $data
     * @param int $code
     * @param bool $isHttpCode $code是否作为http的状态码，默认否
     * @return \Illuminate\Http\JsonResponse
     */
    public function success(string $message = "", array $data = [], int $code = Response::HTTP_OK, $isHttpCode = false): \Illuminate\Http\JsonResponse
    {
        $data = ['status' => 1, 'code' => $code, 'message' => $message ?: __('common.success'), 'data' => $data];
        $status_code = Response::HTTP_OK;
        if ($isHttpCode) {
            $status_code = Str::substr($code, 0, 3);
        }
        return response()->json($data, $status_code);
    }

    /**
     * 场景：操作失败
     * @param string $message
     * @param int $code
     * @param bool $isHttpCode $code是否作为http的状态码，默认是
     * @return \Illuminate\Http\JsonResponse
     */
    public function error(string $message = "", int $code = Response::HTTP_BAD_REQUEST, $isHttpCode = false): \Illuminate\Http\JsonResponse
    {
        $data = ['status' => 0, 'code' => $code, 'message' => $message ?: __('common.error')];
        if ($this->log_id > 0) {
            $data['e_code'] = $this->log_id;
        }
        $status_code = Response::HTTP_OK;
        if ($isHttpCode) {
            $status_code = Str::substr($code, 0, 3);
        }
        return response()->json($data, $status_code);
    }

    /**
     * 场景：接口不存在、模型不存在等 404
     * @return \Illuminate\Http\JsonResponse
     */
    public function errorHttpNotFound()
    {
        return $this->error(__('common.http_not_found'), Response::HTTP_NOT_FOUND, true);
    }

    /**
     * 场景：服务器内部错误、程序错误
     * @return \Illuminate\Http\JsonResponse
     */
    public function errorHttpInternalServerError($message = "")
    {
        return $this->error($message ?: __('common.http_internal_server_error'), Response::HTTP_INTERNAL_SERVER_ERROR, true);
    }

    /**
     * 场景：无权限
     * @param string $message
     * @return \Illuminate\Http\JsonResponse
     */
    public function errorPermission($message = "")
    {
        return $this->error($message ?: __('auth.error_permission'), Response::HTTP_FORBIDDEN);
    }

    /**
     * 场景：添加成功
     * @param array $data
     * @return \Illuminate\Http\JsonResponse
     */
    public function successStored($data = [])
    {
        return $this->success(__('common.success_stored'), $data, Response::HTTP_CREATED);
    }

    /**
     * 场景：添加失败
     * @param string $message
     * @return JsonResponse
     */
    public function errorStored($message = "")
    {
        return $this->error($message ?: __('common.error_stored'));
    }

    /**
     * 场景：删除成功
     * @param array $data
     */
    public function successDestoryed()
    {
        return $this->success(__('common.success_destroyed'), [], Response::HTTP_NO_CONTENT);
    }

    /**
     * 场景：删除失败
     * @param string $message
     * @return JsonResponse
     */
    public function errorDestoryed($message = "")
    {
        return $this->error($message ?: __('common.error_destroyed'));
    }

    /**
     * 场景：修改成功
     * @param array $data
     */
    public function successUpdated($data = [])
    {
        return $this->success(__('common.success_updated'), $data, Response::HTTP_CREATED);
    }

    /**
     * 场景：修改失败
     * @param string $message
     * @return JsonResponse
     */
    public function errorUpdated($message = "")
    {
        return $this->error($message ?: __('common.error_updated'));
    }


    /**
     * 场景：上传成功
     * @param array $data
     */
    public function successUploaded($data = [])
    {
        return $this->success(__('attachment.success_uploaded'), $data);
    }

    /**
     * 场景：上传失败
     * @param array $data
     */
    public function errorUploaded($message = "")
    {
        return $this->error($message ?: __('attachment.error_uploaded'));
    }


    /**
     * 场景：登录成功
     * @param array $data
     */
    public function successLogin($data = [])
    {
        return $this->success(__('login.success_login'), $data);
    }

    /**
     * 场景：用户名密码错误等登录失败情况
     * @param array $data
     */
    public function errorLogin($message = "")
    {
        return $this->error($message ?: __('login.error_login'), Response::HTTP_UNAUTHORIZED);
    }

    /**
     * 场景：未登录，token不存在情况
     * @param array $data
     */
    public function errorLoginNotToken()
    {
        return $this->error(__('login.token_not_exist'), Response::HTTP_UNAUTHORIZED);
    }

    /**
     * 场景：token登录状态过期情况
     * @param array $data
     */
    public function errorLoginTokenExpired()
    {
        return $this->error(__('login.expired'), Response::HTTP_UNAUTHORIZED);
    }
}
